package com.minsf.rpc.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.Setting;
import cn.hutool.setting.dialect.Props;
import cn.hutool.setting.yaml.YamlUtil;
import org.yaml.snakeyaml.Yaml;

import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Description 配置工具类
 * @Author minify
 * @Date 2024/3/24 19:20
 * @Project sf-rpc
 */
public class ConfigUtils {

    public static <T> T localConfig(Class<T> clazz, String prefix) {
        return localConfig(clazz, prefix, "");
    }

    private static <T> T localConfig(Class<T> clazz, String prefix, String environment) {

        T t;

        try {
            t = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        T loadProperties = loadProperties(clazz, prefix, environment);

        T loadedYMAL = loadYmal(clazz, prefix, environment);
//        System.out.println("loadProperties = " + loadProperties);
//        System.out.println("loadedYmal = " + loadedYmal);
        CopyOptions copyOptions = CopyOptions.create().setOverride(true);

        String propSuffix = ".properties";
        String propConfigPath = getConfigPath(environment, propSuffix);
        if (!FileUtil.exist(propConfigPath)) {
            BeanUtil.copyProperties(loadedYMAL, t, copyOptions);
        }

        String ymlSuffix = ".yml";
        String ymlConfigPath = getConfigPath(environment, ymlSuffix);
        if (!FileUtil.exist(ymlConfigPath)) {
            BeanUtil.copyProperties(loadProperties, t, copyOptions);
        }
        if (!FileUtil.exist(propConfigPath) && !FileUtil.exist(ymlConfigPath)) {
            BeanUtil.copyProperties(loadedYMAL, t, copyOptions);
        }

//        System.out.println(t);
        return t;
    }

    private static String getConfigPath(String environment, String suffix) {
        StringBuilder configFileBuilder = new StringBuilder("application");
        if (StrUtil.isNotBlank(environment)) {
            configFileBuilder.append("-").append(environment);
        }
        configFileBuilder.append(suffix);
        return configFileBuilder.toString();
    }

    private static <T> T loadProperties(Class<T> clazz, String prefix, String environment) {
        String configFilePath = getConfigPath(environment, ".properties");
        if (FileUtil.exist(configFilePath)) {
            Props props = new Props(configFilePath);
//            props.autoLoad(true);
            return props.toBean(clazz, prefix);
        } else {
            try {
                return clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

    }

    private static <T> T loadYmal(Class<T> clazz, String prefix, String environment) {
        String configFilePath = getConfigPath(environment, ".yml");
        T config = null;

        if (FileUtil.exist(configFilePath)) {
            String yamlContent = FileUtil.readString(configFilePath, StandardCharsets.UTF_8);
            // 使用 Hutools 的 Setting 类解析 YAML 内容（注意：这里可能会有限制，因为 Hutool 不是完全的 YAML 解析器）
//            System.out.println(yamlContent);
//            Setting setting = new Setting(yamlContent);
            Dict dict = YamlUtil.loadByPath(configFilePath);
            Yaml yaml = new Yaml();
            Object load = yaml.load(yamlContent);
            if (dict.get(prefix) != null) {
                config = (T) BeanUtil.toBean(dict.get(prefix), clazz);
            }
            System.out.println(dict);
        } else {
            try {
                config = clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return config;
    }
}
